package com.mjk.common.util;


import com.mjk.common.base.constns.BeeCommonConstns;
import com.mjk.common.base.error.BizException;
import com.mjk.common.tools.gson.GsonUtils;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.tools.xml.XmlUtils;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StrUtils {
	/**
	 * 如果obj是null 返回抛出message的异常信息
	 * @param obj
	 * @param message
	 */
	public static void notNull(Object obj, String message) {
		if (obj == null) {
			throw new  IllegalArgumentException(message);
		}
	}
	/**
	 * 首字母转大写
	 * @param s 字符串
	 * @return
     */
	public static String toUpperCaseFirstOne(String s) {
		notNull(s, "s must not null");
		if (Character.isUpperCase(s.charAt(0))) {
			return s;
		}
		return Character.toUpperCase(s.charAt(0)) + s.substring(1);
	}

	/**
	 * 首字母转小写
	 * @param s 字符串
	 * @return
	 */
	public static String toLowerCaseFirstOne(String s) {
		notNull(s, "s must not null");
		if (Character.isLowerCase(s.charAt(0))) {
			return s;
		}
		return Character.toLowerCase(s.charAt(0)) + s.substring(1);
	}

	/**
	 * 字符串是否是数字
	 * @param str 字符串信息
	 * @return true 是数字
     */
	public static boolean isNumeric(String str) {
		if ((str == null) || (str.isEmpty())) {
			return false;
		}
		for (int i = 0; i < str.length(); i++) {
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 去除字符串后面的数字
     */
	public static String removeEndNum(String str){
		String reg = "\\D+(\\d+)$";
		Pattern p2 = Pattern.compile(reg);  
		Matcher m2 = p2.matcher(str);  		
		if(m2.find()){  		    
		    return str.replace(m2.group(1), "");  // 组提取字符串  
		}else{
			return str;
		}	
	}
	/**
	 * 格式化字符串 去除回车 换号 空格
     */
	public static String format(String str) {
		return str.replaceAll("[\r\n]", "");
	}
	
	/**
	 * 集合转string
     */
	public static String join(Iterable<?> iterable, String separator) {
		if (iterable == null) {
			return null;
		}
		return join(iterable.iterator(), separator);
	}
	/**
	 * map转string
     */
	public static String mapToStr(List<String> list, String separator) {
		return join(list, separator);
	}
	/**
	 *
     */
	public static String join(Iterator<?> iterator, String separator) {
		if (iterator == null) {
			return null;
		}
		if (!iterator.hasNext()) {
			return "";
		}
		Object first = iterator.next();
		if (!iterator.hasNext()) {
			return first == null ? "" : first.toString();
		}
		StringBuilder buf = new StringBuilder(256);
		if (first != null) {
			buf.append(first);
		}
		while (iterator.hasNext()) {
			if (separator != null) {
				buf.append(separator);
			}
			Object obj = iterator.next();
			if (obj != null) {
				buf.append(obj);
			}
		}
		return buf.toString();
	}
	/**
	 * 字符串是否包含某个字符
	 * @param str 字符串
	 * @param searchChar 字符
     */
	public static boolean contains(String str, char searchChar) {
		if ((str == null) || (str.isEmpty())) {
			return false;
		}
		return str.indexOf(searchChar) >= 0;
	}
	/**
	 * 下划线抓驼峰
     */
	public static String underlineToHump(String para, boolean isUnderline) {
		if (isUnderline) {
			StringBuilder result = new StringBuilder();
			String[] a = para.split("_");
			for (String s : a) {
				if (result.isEmpty()) {
					result.append(s.toLowerCase());
				} else {
					result.append(s.substring(0, 1).toUpperCase());
					result.append(s.substring(1).toLowerCase());
				}
			}
			return result.toString();
		}
		return para;
	}
	/**
	 * 驼峰转小写下划线
     */
	public static String humpToUnderline(String para, boolean isUnderline) {
		if (isUnderline) {
			StringBuilder sb = new StringBuilder(para);
			int temp = 0;
			for (int i = 0; i < para.length(); i++) {
				if (Character.isUpperCase(para.charAt(i))) {
					sb.insert(i + temp, "_");
					temp++;
				}
			}
			return sb.toString().toUpperCase();
		}
		return para;
	}

	/**
	 * 小写下划线转小驼峰
     */
	public static String underlineToHump(String para) {
		StringBuilder result = new StringBuilder();
		String[] a = para.split("_");
		for (String s : a) {
			if (result.isEmpty()) {
				result.append(s.toLowerCase());
			} else {
				result.append(s.substring(0, 1).toUpperCase());
				result.append(s.substring(1).toLowerCase());
			}
		}
		return result.toString();
	}
	/**
	 * 驼峰转 小写下划线
     */
	public static String humpToUnderline(String para) {
		StringBuilder sb = new StringBuilder(para);
		int temp = 0;
		for (int i = 0; i < para.length(); i++) {
			if (Character.isUpperCase(para.charAt(i))) {
				sb.insert(i + temp, "_");
				temp++;
			}
		}
		return sb.toString().toLowerCase();
	}
	/**
	 * 字符串左边 加 0
     */
	public static String addZero(String code, int len) {
		if (code.length() > len) {
			code = code.substring(0, len);
		}
        StringBuilder codeBuilder = new StringBuilder(code);
        while (codeBuilder.length() < len) {
			codeBuilder.insert(0, "0");
		}
        code = codeBuilder.toString();
        return code;
	}
	
	/**
	 * ascii 码转 string
     */
	public static String asciiToString(String value) {
		StringBuilder sbu = new StringBuilder();
		String[] chars = value.split(",");
        for (String aChar : chars) {
            sbu.append((char) Integer.parseInt(aChar));
        }
		return sbu.toString();
	}
	/**
	 * string 转 ascii 码
     */
	public static String stringToascii(String value, Integer format) {
		StringBuilder sbu = new StringBuilder();
		char[] ch = value.toCharArray();
        for (char c : ch) {
            switch (format) {
                case 2:
                    sbu.append(Integer.toBinaryString(NumberUtils.intValue(c)));
                    break;
                case 8:
                    sbu.append(Integer.toOctalString(NumberUtils.intValue(c)));
                    break;
                case 16:
                    sbu.append(Integer.toHexString(NumberUtils.intValue(c)));
					break;
				default:
					return null;
            }
        }
		return sbu.toString();
	}
	/**
	 * 16进制转2进制
	 * @param hexString 16进制数据
	 * @return 二进制数据
     */
	public static String hex2binary(String hexString) {
		if ((hexString == null) || (hexString.length() % 2 != 0)) {
			return null;
		}
		StringBuilder bString = new StringBuilder();
		for (int i = 0; i < hexString.length(); i++) {
			String tmp = "0000"
					+ Integer.toBinaryString(Integer.parseInt(
							hexString.substring(i, i + 1), 16));

			bString.append(tmp.substring(tmp.length() - 4));
		}
		return bString.toString();
	}
	/**
	 * 2进制转16进制
	 * @param binary 二进制数据
	 * @return 返回的十六进制数据
     */
	public static String binary2hex(String binary) {
		StringBuilder bitMap = new StringBuilder();
		for (int i = 0; i < binary.length() / 4; i++) {
			bitMap.append(Integer.toHexString(Integer.parseInt(
					binary.substring(i * 4, (i + 1) * 4), 2)));
		}
		return bitMap.toString();
	}
	/**
	 * 中文转utf8
     */
    public static String chinese2UTF8(String chineseStr) {
		StringBuilder utf8Str = new StringBuilder();
		byte[] utf8Decode = chineseStr.getBytes(StandardCharsets.UTF_8);
		for (byte b : utf8Decode) {
            utf8Str.append(String.format("%02X", b & 0xFF));
		}
		return utf8Str.toString().toUpperCase();
	}
	/**
	 * 中文转gbk
     */
	public static String chinese2GBK(String chineseStr)  throws UnsupportedEncodingException{
        StringBuilder gbkStr = new StringBuilder();
        byte[] gbkDecode = chineseStr.getBytes("gbk");
        for (byte b : gbkDecode) {
            gbkStr.append(String.format("%02X", b & 0xFF));
		}
        return gbkStr.toString().toUpperCase();
	}
	/**
	 * gbk转中文
     */
    public static String gbk2Chinese(String gbkStr) {
		try {
            byte[] b = hexstringtobytes(gbkStr);
			return new String(b, "gbk");
		} catch (Exception e) {
			BizLogger.error(e);
		}
		return "";
	}
	/**
	 * char 2 btye
     */
	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}
	/**
	 * btye 转 16进制
     */
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder();
		if ((src == null) || (src.length == 0)) {
			return null;
		}
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
		return stringBuilder.toString();
	}
	/**
	 * 16进制 转2进制
     */
	public static byte[] hexstringtobytes(String hexstring) {
		hexstring = hexstring.toUpperCase();
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] bs = new byte[hexstring.length() / 2];
		for (int i = 0; i < hexstring.length(); i += 2) {
			char c = hexstring.charAt(i);
			char c1 = hexstring.charAt(i + 1);
			bs[0] = ((byte) (charToByte(c) * 16 + charToByte(c1)));
			bos.write(bs, 0, 1);
		}
		return bos.toByteArray();
	}
	/**
	 * 字符转16进制
     */
	public static String stringToHexString(String str, int len) {
		StringBuilder hexStr = new StringBuilder();
		for (byte b : str.getBytes()) {
			hexStr.append(String.format("%02x", b & 0xFF));
		}
		while (hexStr.length() % len != 0) {
			hexStr.append("0");
		}
		return hexStr.toString();
	}
	
	/*
	* unicode编码转中文
	*/
	public static String decodeUnicode(String unicode) {
		if (unicode.contains("&#x")) {
			unicode = unicode.replace("&#x", "\\u");
		}
		if(unicode.contains(";")){
			unicode = unicode.replace(";", "");
		}
		StringBuilder string = new StringBuilder();
		String[] hex = unicode.split("\\\\u");
        for (String s : hex) {
            try {
                // 汉字范围 一-龥 (中文)
                if (s.length() >= 4) {// 取前四个，判断是否是汉字
                    String chinese = s.substring(0, 4);
					int chr = Integer.parseInt(chinese, 16);
					boolean isChinese = isChinese((char) chr);
					// 转化成功，判断是否在 汉字范围内
					if (isChinese) {// 在汉字范围内
						// 追加成string
						string.append((char) chr);
						// 并且追加 后面的字符
						String behindString = s.substring(4);
						string.append(behindString);
					} else {
						string.append(s);
					}
                } else {
                    string.append(s);
                }
            } catch (NumberFormatException e) {
                string.append(s);
            }
        }
		return string.toString();
	}
	
	/**
	 * 字符串是否有中文
     */
	public static boolean isChinese(String str) {
		if ((str == null) || (str.isEmpty())) {
			return false;
		}
		for (int i = 0; i < str.length(); i++) {
			if (isChinese(str.charAt(i))) {
				return true;
			}
		}
		return false;
	}
	/** 
     * 判断是否为中文字符 
     *
     */  
    public static boolean isChinese(char c) {  
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
    }  
    /**
     * 获取 匹配正则的字符串
     */
	public static String getMatcher(String regex, String source) {  
        String result = "";  
        Pattern pattern = Pattern.compile(regex);  
        Matcher matcher = pattern.matcher(source);  
        while (matcher.find()) {  
            result = matcher.group(1);
        }  
        return result;  
    }  


	/**
	 * 获取字符串中的数字
     */
    public static String getNumbers(String content) {
        Pattern p = Pattern.compile(BeeCommonConstns.NUMBER_MATCH);
		  Matcher m = p.matcher(content);  
		  return m.replaceAll("").trim();
	  } 
	 /**
	  * byte 转String
      */
	public static String byte2String(byte[] by){
		return byte2String(by, "utf-8");
	}

	/**
	 * byte 转字符串
	 * @param by
	 * @param formate
	 * @return
	 */
	public static String byte2String(byte[] by,String formate){
		try {
			String s = new String(by,formate);
			if(ObjectUtils.isEmpty(s)){
				return "";
			}
			return s.trim();
		} catch (UnsupportedEncodingException e) {
            throw new BizException(e);
        }
	}

	/**
	 * 获取文本长度。汉字为1:1，英文和数字为2:1
	 *
	 * @param text 水印文字
	 * @return 文字的长度
	 */
	public static int getTextLength(String text) {
		int length = text.length();
		for (int i = 0; i < text.length(); i++) {
			String s = String.valueOf(text.charAt(i));
			if (s.getBytes().length > 1) {
				length++;
			}
		}
		length = length % 2 == 0 ? length / 2 : length / 2 + 1;
		return length;
	}
	/**
	 * 某个字符出现的次数
     */
	public static int searchStrNumber(String str, String strRes) {
		int n = 0;
		int index;
		index = str.indexOf(strRes);
		while (index != -1) {
			n++;
			index = str.indexOf(strRes, index + 1);
		}
		return n;
	}
}
